home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-12-09 | 35.1 KB | 849 lines | [TEXT/KAHL] |
- O.I.C Objects-in-C
- ===================
-
- Explorer's Kit Documentation
-
- Copyright © John Wainwright, 1988
-
- 454 West 20th Street, #2
- New York, NY 10011
-
- Compuserve : 72657,2534
-
- All rights reserved
-
- Shareware fee : $20
-
- This is the shareware, explorer's release of a portable
- object-oriented programming environment for the C pro-
- gramming language. The kit contains the complete objects
- environment, a bunch of simple, but useful demo classes
- and this, EXPERTS ONLY, documentation - enough for ex-
- perienced C programmers that know something about object-
- oriented techniques to take advantage of them in the
- excellent C environments now on the Mac.
-
- It is supplied as a verion 3, LightSpeed C project but
- the source files are simple text files that should be
- readable by any of the Macintosh C compilers.
-
- The full release will come with complete documentation
- and an EXTENSIVE set of classes for developing Mac
- applications - a persistent object store, a complete
- Model-View-Controller system for accessing the Mac
- toolbox, 2D & 3D PHIGGS-like imaging spaces integrated
- with the MVC system, a polymorhpic, object-oriented
- spreadsheet system, and an embeddable Common Lisp
- subset interpreter with OIC interface.
-
- Acknowledgements: Tim Long and Andrew Nicholson
- both contributed materially to
- the ideas in this system.
-
- Introduction
-
- OIC is a state-of-the-art object-oriented programming environment for
- the C programming language implemented as a portable library of
- management routines and a set of programming conventions. It
- features the following :
-
- • A fully dynamic class structure
- • Multiple inheritence
- • Class variables & class methods
- • Generic function method dispatch with method caching
- • True run-time polymorphism
- • Support for multi-methods
- • No need for a special pre-processor - will work with ANY C
- • High speed access to instance variables via C structures
- • Method dispatch tracing system
- • Smooth & arbitrary transition between C & OOP code
-
- OIC has more of the flavor of the dynamic, Lisp-based OOPS &
- SmallTalk than of the static languages like C++ and Object Pascal.
- Some of the features, like generic functions, are reasonably
- avant-garde, and are described in the following sections.
-
- There is one major departure from the semantics of these OOP systems
- as a consequence of using no pre-processor & deciding to access
- instance variables via C structures: instance variables effectively
- have a SINGLE level of scoping. See the section on Limitations, below
- for a full discussion.
-
- This document assumes a detailed familiarity with C and a reasonable
- understanding of object-oriented programming techniques. For those
- without the latter, try "Object-Oriented Programming for the
- Macintosh" by Kurt Schmucker or "Object-Oriented Programming in
- Common Lisp" by Sonya Keene. The following sections describe the
- implementation approach & memory structures, OIC limitations and
- the example file set. At the end is a reference list of library
- functions & macros, some warnings about portability limitations,
- and details of the shareware licence.
-
- ------------------
-
- Implementation
-
- This section describes the 3 prime elements of the OIC
- system :
-
- • object layout, management and access
- • class layout, management and access
- • generic function & method creation and dispatch
-
- All 3 involve structures created & managed at run-time by the OIC
- library. In this version, ALL the structures are allocated as
- handles, locked & then dereferenced. This is NOT good form, but
- seems to be the quickest memory management scheme on the Mac. If
- it offends you, the storage allocation routines in "memory.c" can
- be changed to suit. The decision to use pointers & not handles
- was to promote portability to C environments other than on the
- Macintosh; a future version may use handles.
-
- Objects
-
- Objects are layed-out in memory as a class tag followed by
- the concatenation of all the instance variables (IVs) defined
- in the object's component classes - i.e., its class and all
- its superclasses, and all their super classes, etc. Each
- object is allocated as a single block of memory and the IVs
- are zero-filled. The class tag defines the object's class
- and is actually a pointer to the class's defining structure
- (described below). The IV's defined by each component class
- are mapped & accessed by ordinary C structures - when a method
- is invoked, a pointer is supplied that points to the local
- IV structure, i.e., the IVs defined in the class in which the
- invoked method was found.
-
- Objects are always referred to by pointers. The provided
- "object" typedef declares a pointer storage type that will
- hold a pointer to ANY class of object - the system is
- dynamically polymorhpic. IVs can be any C type including,
- of course, object.
-
- Objects are created with the "New" function. It takes a
- class & any number of following arguments. When created,
- the object has its "new" generic function invoked which
- is passed the other, presumably initialisation, arguments.
-
- It is the programmers responsibilty to explicitly free
- memory occupied by unused objects. The generic function
- "dispose", a method for which is provided in default by
- the root class "Object", will free the originally
- allocated object. This should be specialised
- if any other housekeeping is needed. By convention,
- the generic "deepDispose" will free the object and,
- recursively, any contained objects. This, for example,
- is how the supplied List class lists are freed in one go.
-
- ------------------
-
- Classes
-
- OIC provides full multiple inheritence of methods. This is
- supported by a run-time collection of "Class" objects (yes,
- classes are proper objects) arranged in directed, acyclic
- graph. This D.A.G. maps the inheritence relationships
- among the classes. All classes inherit eventually from
- the root class "Object" which provides a bunch of useful
- default methods. (see "object.c" for its definition).
-
- Each object is tagged by a pointer to its class's object.
- This is how OIC determines an object's class and contrives
- to dispatch the correct method for a given generic function
- invokation. Each class object contains instance allocation
- and IV mapping information, an immediate superclass list,
- the class variables and method invokation information.
- Clearly, a class must exist before any instances of it
- can be created.
-
- The general intention is that each class be defined in a
- separate source file (see examples) to promote information
- hiding, functional independance & all those good things.
- Each file contains the IV & CV structure definitions, a global
- to hold the class object, the methods which are written as
- static functions, and an initializing function that creates
- the class and associates its methods with their generic
- functions (see below).
-
- A class is created by the "NewClass" function. It takes as
- arguments, the size of the IV & CV structures, a class name
- (as a C string) and a null-terminated list of superclasses.
- The order of this list determines the inheritence priority.
- The supplied method finder does a breadth-first search up
- the superclass tree, scanning across the superclass lists
- at each level in the order in which they were specified to
- the NewClass function. Clearly also, "super"classes
- must exist before they can be specialized or mixed-in.
-
- OIC supports class variables and class methods - see the
- "IndexMixin" class for an example of how they work.
-
- ------------------
-
- Generic Functions and Methods
-
- OIC uses the Generic Function (GF) technique of method dispatch,
- prefered in the current state-of-the-art LISP object-oriented
- systems like CLOS, New Flavors, Common Loops, and Object LISP.
- It has several semantic & performance advantages over the
- message passing schemes and embeds exceptionally cleanly in
- functional languages (like C).
-
- Instead of sending a message identifier to an object as in
- SmallTalk, or qualifying a function name by a class name as in
- Object Pascal, the generic function is a single function
- defined over a number of argument classes. It acts like
- a dispatcher which invokes the appropriate method (or methods)
- depending on the class of one (or more) of its arguments and
- hence is "generic". In the terminology a "generic function"
- embodies many operations depending on the class of its
- arguments. The different operations are defined by "method
- functions", one in each of the classes that will directly
- handle that generic.
-
- For example, in a messaging-passing system we might have :
-
- send("append", list, item);
-
- In a GF system this becomes :
-
- append(list, item);
-
- "append" being a function which dispatches to one of the
- various appending methods depending on the class of its first
- argument. This is clearly the preferred form for embedding
- in C. Apart from looking good, a number of neat things follow
- from this technique.
-
- Firstly, it is very simple to write high-speed, caching
- method dispatchers, usually requiring only a single indexing
- operation to get the method required.
-
- Secondly, individual generic functions can be made to have
- their own dispatching semantics by allowing programmers to
- straight-forwardly define their own dispatching functions.
-
- For example, generic functions can be cleanly made to be driven
- by the classes of several arguments, not just one, allowing
- the implementation of so-called multi-methods. In a
- mixed-mode arithmetic system, we might have something like :
-
- add(a, b);
-
- where a & b have different classes & hence some coercion is
- required. A dispatching function for a set of math generic
- functions might look at the classes of the arguments, decide
- on the mutually widest class, invoke coercion generics on
- a & b to that wider class & invoke the add generic on the
- coercions :
-
- add(coerce(a, wide), coerce(b, wide));
-
- Another example might be a dispatching function that will handle
- before, after & around methods in the way of ZetaLisp's Flavors.
-
- Defining Generic Functions
-
- OIC comes supplied with only a single kind of generic function;
- one that dispatches on the class of the first argument -
- equivalent to simple message-passing. If inheritence is
- needed it follows a BREADTH-FIRST search up the superclass tree
- caching any found methods for subsequent single-index dispatch.
-
- Generic functions of this simple type are defined using the
- "defGeneric" macro (defined in "object.h"). This macro is
- unfortunately very unwieldly - it requires 3 arguments which
- are just variants of the generic's name (if ONLY one could
- construct symbols & strings in the standard C preprocessor!!!)
- It declares a function with the generic's name having the
- above-mentioned dispatching semantics and declares some tables
- that hold pointers to the method functions. This method
- table is used by the dispatching code and is in two parts,
- one for normal methods & the other for class methods; they
- are both indexed by a unique "class index" which is allocated
- when the class is created.
-
- Other kinds of dispatching semantics would be implemented by
- defining and using variants of the defGeneric macro. The
- technique allows multiple concurrent defGeneric variants.
-
- Defining & Invoking Method Functions
-
- As mentioned in the Class section above, the various methods
- for a class are usually defined as static functions in that
- class's source file. Method functions are passed 3
- arguments on invokation: the dispatching object, a pointer
- to the local IV structure in that object, and a pointer
- to the rest of the arguments given to the generic. For
- example, the generic invokation :
-
- set(window1, "Untitled", &rect1, VISIBLE);
-
- would result in calling a method function declared :
-
- static object
- set_method(self, ivs, args)
- object self;
- window_iv *ivs;
- struct
- {
- char *title;
- Rect *frame;
- int visFlag;
- } *args;
- {
- .....
- ivs->title = args->title;
- .....
- set_frame(self, args->frame);
- .....
- return self;
- }
-
- such that "self" points to the key object "window1",
- "ivs" points to the "window_iv" structure within that
- object (remember all the IV structures of the component
- classes are concatenated to form an object), and "args"
- points to the string & the rectangle arguments.
-
- The "args" argument actually points into the call frame
- of the generic function "set" at its secondary arguments
- on the stack. This is done for speed & so the dispatcher
- doesn't have to know how many arguments there are. This is
- guarranteed to work only in C implementations that use
- the stack for passing arguments (all the C's on the Mac).
- Some C's on large machines with millions of registers use
- them instead of the stack for argument passing and OIC's
- technique wont work (see portability limitations, below).
-
- Also, on those C's that use the stack, structures are
- layed-out in the same way as arguments on the stack,
- so the in-line argument structure declaration is a neat
- way of getting at these "passed-on" arguments. Remember,
- though, that chars are widened to ints and floats to doubles
- when being placed on the argument stack - they must be
- declared as this widened form in the argument mapping
- struct.
-
- Note in the example, above, how the IVs & arguments are
- accessed in clean, high-speed ways.
-
- Associating Methods with Generic Functions
-
- A generic function is implemented by a bunch of method
- functions, one from each of the classes that is so
- inclined. The association of a method with its generic
- is usually done in the class source file, in the initializing
- function that creates the class (see the example classes).
-
- The function "AddMethod" performs this task and is tuned
- to take a bunch of methods defined in one class & associate them
- one-by-one with each's particular generic. It takes a class object
- as its first argument followed by a null terminated list of
- pairs: the generic's method table (declared by "defGeneric") and
- the method function, e.g.
-
- AddMethods(List, appendGeneric, appendMethod,
- headGeneric, headMethod,
- tailGeneric, tailMethod,
- ....,
- NULL);
-
- AddMethods can be called any time and any number of times after
- a class has been created to incrementally add its methods. An
- equivalently argumented function called "AddClassMethods" will
- add class methods to the generics specified. (see IndexMixin.c
- for an example).
-
- ------------------
-
- Limitations
-
- Embedding such a system in standard C necessarily involes trade-
- offs. Some of these have resulted in limitations and others
- in the need for rather cryptic code.
-
- Scope and Inheritence of Instance Variables
-
- The decision to map object instance variables by C
- structures results in the only major departure from
- conventional OOPS semantics - the SCOPE of instance
- variables is effectively limited to the level in the class
- hierarchy that defines them. This single level of
- scoping immediately implies that ALL instance & class
- variables are inherited; there is no "hiding" of similarly-
- named instance variables up the inheritance chain
- as occurs in some other OOP systems.
-
- Some would contend that this is due & proper adherence
- to the programming principles of encapsulation and,
- fortunately, it rarely causes problems - one tends to be
- interested in the goings-on of the IVs in the
- methods of the class that defined the IVs. However,
- on some occasions, especially when slightly specialising
- an existing class, it is handy to be able to get at the
- IVs for that class, and there are 2 ways to achieve this.
-
- The first is to use one of the macros "localIVs" or "myIVs".
- The first allows you to reach into any object of the same
- class as "self" and get IV structure for the current
- method's class. "myIVs" reaches into "self" and gets the
- IVs for any one of its superclasses. See Macros, below for
- further details.
-
- The second way is to use methods to access IVs. Indeed, most
- of the Lisp OOPS do it this always; the OOPS system
- automatically generating the accessing methods - very easy
- to do in Lisp, not so in C. This technique can, of course,
- be used on an IV-by-IV basis; provide access methods for
- only those that will need to be accessed by specializing
- classes. Because inherited methods have a nested scoping -
- closer ones hide ones farther up the inheritence chain - this
- technique also provides a way of implementing nested
- inheritence of selected IVs.
-
- ------------------
-
- Source File Structure & Coding Conventions
-
- In the example classes and according to the recommended way of
- using OIC there is one source file for each class. This
- yields a convenient modularity and allows the desired
- kinds of information hiding to be set up. Each class
- source file usually contains :
-
- 1. The IV & (possibly) CV structure definitions.
- They will need to be moved out into an include
- file if several classes (which should always
- be inheriting classes) are to get at them.
-
- 2. A class global to hold the class object.
-
- 3. The methods defined in this class, usually
- as static functions. Note in the example
- classes that these are named with the
- generic name prefixed by an underscore - you
- might be happier with the generic name post-
- fixed with "Method"; in any event, they must
- be different from the actual generic function's
- name.
-
- 4. Any local utility function that the above might use.
-
- 5. An initializing function that creates the class
- and associates its methods with their corresponding
- generics. This function needs to be called during
- initialization in the main code.
-
- The declaring of generic functions requires some care. They
- are intended to be program-wide globals and are probably best
- all declared in one spot because almost any class might
- wind up defining a method for one. In the example file set
- they are all declared in "generics.c". They also need to be
- declared external in all the source files that might use
- them; in the example kit this is done in the include file
- "generics.h".
-
- Any file that uses OIC should include "oic.h" - it defines
- all the OIC typedefs, macros & externals.
-
- ------------------
-
- Example File Set
-
- This explorer's kit is intended primarily to place a working
- object-oriented C programming mechanism into the hands of
- expert C programmers for their edification, enjoyment and,
- hopefully, serious use. The demo classes and small test
- main program are not intended to be a tutorial on OOPS
- programming, nor to necessarily form the basis for a serious
- suite of classes. They are simply the test classes I built
- as OIC came together, suffer somewhat from its growing
- pains, and are provided to help illuminate the basic
- object manager.
-
- The base object manager is represented in the files :
-
- oic.c - the basic management routines
- memory.c - customizable object allocation routines
- oic.h - the include file for anybody using oic
- object.c - the root class
- class.c - the class class
-
- Certain of the class files go to make up whats called the
- system classes :
-
- list.c - a general purpose list class
- string.c - a class to hold C strings
- replist.c - a representation class for nested objects
- collect.c - a generic superclass that adds lots of
- neat collection methods to any class that
- provides head, tail, push & eq
- list2.c - a version of the list class using Collect
- indexMixin.c - a mixin (a modifying superclass) that will
- keep track of all the instances of a class
- that uses it as a superclass
- linkseq.c - a general purpose sequencing class for
- classes that understand head, tail & isEmpty
- generics.c - defGenerics for all the above classes
- generics.h - external definitions for the above classes
-
- Notes:
-
- 1. The List class does NOT implement standard LISP lists, the
- operations all destructively modify the subject list. It
- will only hold OIC objects as elements.
- 2. The IndexMixin class provides an example of how to use
- class variables & class methods. It specializes the "new"
- method & maintains a list (using the List class) of each
- instance of a class inheriting from it in a class variable.
- They can be got by invoking "allInstances" on the class you
- are keeping track of. It also adds a "sequence" class method
- so you can simply sequence over the class.
- 3. The Replist class is a specialization of the List class
- intended to help formatting & printing nested objects
- like Lists. It gets used by the repList methods in various
- classes to create a structure isomorphic to the object
- being printed but with String representations of the
- object's leaf values instead of the values themselves.
- This can then be neatly parenthesised & indented, etc. See
- how it gets used by looking at the print method in the
- root Object class (object.c). This print method is
- inherited by EVERY class and so provides a simple
- object printer for any class that can generate a Replist
- of itself (see List).
- 4. the Linkseq class is an example of what could be
- a suite of sequencing utility classes. Its purpose is
- to wrap up an object that is being sequenced over to
- provide the sequencing context. Note how it gets used
- in the test program, main.c. There are several
- "for" statements that invoke the "sequence" generic on
- an object. Any object that is sequencable should
- define a sequence method that will wrap itself up
- in, and return, one of these utility sequence classes.
- This class should, in turn, respond to the generics
- "start", "next", "moreInSeq", & "restart". Other
- kinds of sequence "wrapper" classes might work for
- scalars by generating consecutive values, strings by
- sequencing through the characters, or arrays by indexing
- through their elements. See how neatly (in main.c) we get
- general purpose polymorphic sequencing in an ordinary
- old C "for" statement.
-
- A small test program with some other little classes is
- contained in the files :
-
- main.c - the main test procedure
- coord.c - a kind of point class
- box.c - a kind of rectangle class
- window.c - a trivial window class that experiments
- with keyword arguments!
-
- ------------------
-
- OIC System Typedefs
-
- typedef struct class *class - declares a holder for a class object
- typedef struct class **object - declares a holder for an object
-
- OIC System Functions
-
- class NewClass(iv_size, cv_size, name, super1, super2, ... NULL)
- int iv_size;
- int cv_size;
- char *name;
- class super1, super2, ...;
-
- creates a new class with local IV & CV structure sizes as given
- and that inherits from the null-terminated list of superclasses.
- The order of this list determines the inheritence priority.
- The supplied method finder does a breadth-first search up
- the superclass tree, scanning across the superclass lists
- at each level in the order in which they were specified to
- the NewClass function.
- The class name is used for debugging & tracing output.
-
- object New(class, initializing arguments ...)
- class class
- <any> initializing arguments ...;
-
- creates a new object of the given class. Invokes the "new"
- generic on the fresh object, passing it the initialization
- arguments.
-
- void AddMethods(class, generic1, method1, generic2, method2, ..., NULL)
- class class;
- MethodTable generic1, generic2, ...;
- <any> (*method1)(), (*method2)() ...;
-
- associates methods for the given class with their generic
- functions. The generics are specified by passing the method
- table that is created by the "defGeneric" macro (see below).
-
-
- void AddClassMethods(class, generic1, method1, generic2, method2, ..., NULL)
- class class;
- MethodTable *generic1, *generic2, ...;
- <any> (*method1)(), (*method2)() ...;
-
- associates class methods for the given class with their generic
- functions. The generics are specified by passing the method
- table that is created by the "defGeneric" macro (see below).
-
- object Super(object, arguments...)
- object object;
- <any> arguments;
-
- invokes the method for the currently executing generic that is
- next higher up the inheritance path than the current method. This
- is very useful when one wishes merely to augment the operation
- of an inherited method, rather than completely replace it.
-
- object SuperPassArgs(object, argumentListPtr)
- object object;
- <any> *argumentListPtr;
-
- same as "Super" but a pointer to the argument list is given
- rather than specifying them in place. This is useful for passing
- the argument list pointer that a method normally gets straight
- through to the super method.
-
-
- int SizeOf(object)
- object object;
-
- returns the total size of the object in bytes.
-
- char *ClassNameOf(object)
- object object;
-
- returns the class name of the object as a C string.
-
- char *MethodName(generic)
- MethodTable *generic;
-
- returns the name of a generic as a C string given the generics
- method table (as defined by "defGeneric", see below).
-
- int IsA(object, class)
- object object;
- class class;
-
- returns true if the object is of the given class.
-
- int IsAKindOf(object, class)
- object object;
- class class;
-
- returns true if the object is of the given class or inherits from
- that class.
-
- int IsObj(object)
- object object;
-
- attempts to check whether object is a valid object. It does
- this by ensuring that "object" is a valid pointer, points into
- the application heap, points at a tag that points at a class
- which itself has a tag which must point to the "Class" object.
- Clearly, it can be fooled, so beware.
-
- void InitOIC()
-
- creates & initializes the OIC system. Should be called
- EXACTLY once before any of the OIC functionality is used.
-
- void InitSysClasses()
-
- creates & initializes the system classes.
-
- void TraceOn() - turns on generic call tracing
- void TraceOff() - turns it off
- void TraceObj(object) - traces any generics called on object
- void TraceClass(class) - traces any generics ony any "class" object
- void dumpClass(class) - debugging class dump
- void dumpMethodTable(mth) - debugging method table dump
-
- OIC System Globals
-
- class currentClass; - the class in which the currently executing
- method was found.
- class classes; - a linked list of all classes created. You can
- get a List of the classes by invoking subs(Object);
- class Class; - the class class.
- class Object; - the root object class. ALL classes inherit
- eventually from Object
-
- Object methods
-
- The following methods are provided as defaults by the root class Object.
- ALL classes, therefore, support these methods by default inheritence.
-
- eq(obj1, obj2) - a byte wise comparison of the contents of each
- new(obj, args...) - dummy "new" method
- className(obj) - class name as a String object
- print(obj) - invokes print(repList(obj))
- repList(obj) - default object representation. creates a
- replist by stepping through obj
- sizeof(object) (4 bytes) at a time. If
- the current 4 bytes is a valid object
- reference recursively calls repList,
- otherwise adds a hex representation to
- the repList
- map(obj, f) - maps the function "f" over each item in "obj"
- by using "sequence" on "obj".
- dispose(obj) - frees the memory occupied by "obj"
-
- Class methods
-
- supers(class) - returns a (List) list of all the classes ancestors
- subs(class) - returns a (List) list of all the classes that
- inherit from "class"
- print(class) - prints the class name
- repList(class) - returns the class name as replist
-
-
- OIC System Macros & Defines
-
- defGeneric(generic, methodTable, name)
-
- declares a generic function and its attendant method table.
- This macro must be called once for each unique generic
- function in the system - generics are global functions.
- The macro is given the generic's name, the name to be used
- for the generic's method table, and the generic's name as
- a C string constant.
-
- If C's preprocessor were even the tiniest bit smart it would
- allow one to create symbols & strings & you have only had to
- give defGeneric one argument. Ah, well.
-
- For example :
-
- defGeneric(print, printGeneric, "print");
-
- externGeneric(generic, methodTable)
-
- declares an external reference to a generic function.
- Usually both the generic function itself and its
- method table need to be accessible, and this macro
- eases their declaration. (see generics.h)
-
- For example :
-
- externGeneric(print, printGeneric);
-
- localIVs(obj, structure)
-
- computes a pointer to the IV structure in "obj" for
- to the current class. This is useful if I'm working
- with two objects of the same class (say, Lists that
- I'm concatenating) and I want to reach into the
- IV's of both of them (see _join in list.c). The
- "structure" argument is just used to cast the
- resulting pointer to that which you want (the
- structure typedef for the current class's IVs).
-
- myIVs(class, structure)
-
- computes a pointer to the IVs of "self" for the
- given "class". This is the macro that gets around
- the one-level scoping problem - I can reach back
- and get at the IVs of any superclass I want (providing
- the structure typedefs are available - you may
- want to enforce the hiding by keeping these typedefs
- private).
-
- localCVs(class, structure)
-
- as for localIVs but point at the class variables instead.
-
- myCVs(class, structure)
-
- as for myIVs but point at the class variables instead.
-
- ClassOf(object)
-
- computes the class of the given object
-
- CHECK_OBJS
-
- if defined in "oic.c" will cause all oic functions to
- check for valid class & object arguments (by using IsObj()).
- This is a conditional assembly flag and is set in the
- distributed kit.
-
- END
-
- equivalent to NULL. Used sometimes to mark the end
- of argument lists. Another gripe: why didnt they
- design C so you could find out how many arguments you
- were given - after all, the function call form is
- completely polymorphic - I can understand the lack in
- a language with compile-time isomorphism checks like
- Pascal.
-
- ------------------
-
- Portability Considerations
-
- There is really only one major portability consideration and that
- involves OIC's expectations about the use of the stack for passing
- arguments. It expects all arguments to be placed on the stack
- with earlier arguments at lower addresses.
- On 680x0s and 80x86s there is no other sensible option and so
- OIC should port without trouble on C compilers for those machines
- (the techniques have been tried on 68010 Unix 4.2BSD and 80286
- Xenix & MS-DOS boxes succesfully).
-
- OIC was developed in THINK's Lightspeed C, an extremely good C
- development environment for the Macintosh. It has also run without
- change using Aztec C.
-
- The current version does make use of UNIX-like standard I/O calls
- for outputing errors and trace messages. Both LSC and Aztec provide
- a Unix emulation library for this. You may have trouble if your C
- doesn't, in which case you should recode all the printf's &
- fprintf's. Indeed, in the full OIC, this use of Unix emulation
- will go and be replaced by the use of generic, stream-based text
- window classes.
-
- ------------------
-
- Licensing Terms
-
- This software is distributed as shareware; if you wind up using it
- for developing any software, particularly commercial software, please
- send the $20 fee to the address below. You will become a registered
- user and have access to upgrades & class kits as they become
- available.
-
- The software is also distributed AS IS, with no warranty, expressed or
- implied, of the correctness or suitability of this software for any purpose.
- No responsibility is assumed for damages arising from the use of this
- software.
-
- OIC is protected by copyright and all commercial rights are reserved.
- Under NO circumstances may this software be distributed in any decodable
- source form, or any form that might be usable as a programming tool
- for commercial advantage. Reasonable duplication costs can be charged.
-
- Under the shareware ethic, however, you are free to copy & distribute
- the OIC software UNCHANGED, providing this document & licensing terms
- are also copied & distributed with the OIC software.
-
- Feedback & queries are welcome. I am interested in any classes that
- you may develop - indeed, it seems to me that the success
- of a system like this will primarily be a function of the quantity and
- quality of classes available.
-
-
- Have fun!
-
- John Wainwright
- 454 West 20th Street, #2
- New York, NY 10011
-
- Compuserve : 72657,2534
-
-
- All OIC files & documentation are Copyright © John Wainwright, 1988